﻿using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.Net;
using Newtonsoft.Json;
using System.Security.Cryptography.X509Certificates;
using System;
using System.Net.Security;
public class HttpRequestManager : Singleton<HttpRequestManager>
{
//    public enum HttpRequestType
//    {
//        Login,
//		ResVersion,
//        CheckLink,
//        LinkNew,
//    };

//    public delegate void HttpRequestHandler(string response, WebExceptionStatus type);
//    private Dictionary<HttpRequestType, List<HttpRequestHandler>> _httpRequestEventTable = new Dictionary<HttpRequestType, List<HttpRequestHandler>>();

    private const string LoginApiUrl = "game/DeviceID";
	private const string ResVersionApiUrl = "game/ResVersion";
    private const string CheckGameCenterLinkUrl = "game/link/checklink";
    private const string LinkNewGameCenterUrl = "game/link/linknew";
	private const string UnBindGameCenterUrl = "game/link/unlink";

	private const string CheckFacebookLinkUrl = "game/link/checklinkfb";
	private const string BindFacebookUrl = "game/link/linkfb";
	private const string UnBindFacebookUrl = "game/link/unlinkfb";

    private const string CheckThirdPartLinkUrl = "game/link/checklink3";
	private const string BindThirdPartUrl = "game/link/link3";
	private const string UnBindThirdPartUrl = "game/link/unlink3";

    private Dictionary<int, HttpRequest> dicTrackHttpRequest = new Dictionary<int, HttpRequest>();
    private List<HttpRequest> listTrackHttpRequest = new List<HttpRequest>();
    private const int HttpRetryCount = 5;
    private bool _networkAvailable = true;
//    private const int BUFFER_SIZE = 1024;

//    private Dictionary<HttpRequestType, HttpRequest> _dicTypeToRequest = new Dictionary<HttpRequestType,HttpRequest>();
//    private List<HttpRequest> _arrRequest = new List<HttpRequest>();

//    public void Subscribe(HttpRequestType type, HttpRequestHandler httpRequestHandler)
//    {
//        if (!_httpRequestEventTable.ContainsKey(type))
//        {
//            _httpRequestEventTable[type] = new List<HttpRequestHandler>();
//        }
//        _httpRequestEventTable[type].Add(httpRequestHandler);
//    }

//    public void Unsubscribe(HttpRequestType type, HttpRequestHandler httpRequestHandler)
//    {
//        if (!_httpRequestEventTable.ContainsKey(type))
//        {
//            return;
//        }
//
//        _httpRequestEventTable[type].Remove(httpRequestHandler);
//        if (_httpRequestEventTable[type].Count == 0)
//        {
//            _httpRequestEventTable.Remove(type);
//        }
//    }

//    public void Login(string postContent, bool cancelPreviousRequest = true)
//    {
//        string reqUrl = HttpRequestManager.GetRequestUrl(LoginApiUrl);
//        
//        if (cancelPreviousRequest)
//        {
//            if (_dicTypeToRequest.ContainsKey(HttpRequestType.Login))
//            {
//                HttpRequest existReq = _dicTypeToRequest[HttpRequestType.Login];
//                existReq.Cancel();
//                _dicTypeToRequest.Remove(HttpRequestType.Login);
//                _arrRequest.Remove(existReq);
//            }
//
//            HttpRequest request = new HttpRequest();
//            _dicTypeToRequest[HttpRequestType.Login] = request;
//            _arrRequest.Add(request);
//            request.Request(reqUrl, postContent, LoginCallback);
//        }
//        else
//        {
//            HttpRequest request = new HttpRequest();
//            _arrRequest.Add(request);
//            request.Request(reqUrl, postContent, LoginCallback);
//        }
//    }
    public HttpRequestManager()
    {
        ServicePointManager.ServerCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)=>{
            return true;
        };
//        DataChangeBroadcast.Instance.Subscribe(DataChangeType.HttpResponse, this.OnHttpResponse);
//        DataChangeBroadcast.Instance.Subscribe(DataChangeType.NetworkAvailable, this.OnNetworkAvailable);
    }
    public object Login(string host, string postContent, System.Action<object, object, byte[], WebExceptionStatus> callBack, System.Func<object, byte[], object> parseDataCallback)
	{
		string reqUrl = HttpRequestManager.GetRequestUrl2(host, LoginApiUrl);
		HttpRequest request = new HttpRequest();
        request.Request(reqUrl, postContent, callBack, parseDataCallback);
		return request;
	}

    public object game(string host, byte[] postContent, System.Action<object, object, byte[], WebExceptionStatus> callBack)
	{
		HttpRequest request = new HttpRequest();
		request.Request(host, postContent, callBack, null);
		return request;
	}

    public string GetRequestUrl(object requestObj)
    {
        HttpRequest request = requestObj as HttpRequest;
        if(request != null)
        {
            return request.url;
        }
        return null;
    }

    public object CheckNewAssetBundle(string url, string deviceId, string appName, string platform, bool isIl2cpp, int il2cppAppVersion, string il2cppPatchMd5, string compileType, int appVersion, string configMd5, System.Action<object, object, byte[], WebExceptionStatus> callBack, System.Func<object, byte[], object> parseDataCallback)
    {
        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("device_id", deviceId);
        dic.Add("app_name", appName);
        dic.Add("platform", platform);
		dic.Add("is_il2cpp", isIl2cpp.ToString());
		dic.Add("il2cpp_app_version", il2cppAppVersion.ToString());
		dic.Add("il2cpp_patch_md5", il2cppPatchMd5);
        dic.Add("compile_type", compileType);
        dic.Add("app_version", appVersion.ToString());
        dic.Add("config_md5", configMd5);
        dic.Add("external_resource_md5", ExternalResourceManager.GetMd5());

        string tempUrl = CombineUrlAndGetParameters(url, dic);
		
        HttpRequest request = new HttpRequest();
        request.Request(tempUrl, null, callBack, parseDataCallback);

        return request;
    }

    public static string CombineUrlAndGetParameters(string url, Dictionary<string, string> getParams)
    {
        bool first = true;
        Dictionary<string, string>.Enumerator e = getParams.GetEnumerator();
        while (e.MoveNext())
        {
            if (e.Current.Key == null || e.Current.Value == null)
            {
                continue;
            }

            if (first)
            {
                url += "?";
                first = false;
            }
            else
            {
                url += "&";
            }

           url += e.Current.Key + "=" + e.Current.Value;
        }

        return url;
    }

    public object Request(string url, System.Action<object, object, byte[], WebExceptionStatus> callBack)
    {
        return Request(url, callBack, null);
    }

    public object Request(string url, System.Action<object, object, byte[], WebExceptionStatus> callBack, System.Func<object, byte[], object> parseDataCallback)
    {
        HttpRequest request = new HttpRequest();
        request.Request(url, null, callBack, parseDataCallback);
        return request;
    }

//    public void CheckGameCenterLink(string deviceId, string uuid, string playerId, HttpRequest.HttpRequestCallback callBack)
//    {
//        Dictionary<string, string> dic = new Dictionary<string, string>();
//        dic.Add("deviceID", deviceId);
//        dic.Add("uuid", uuid);
//        dic.Add("playerID", playerId);
//
//        string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//        string reqUrl = HttpRequestManager.GetRequestUrl(host,CheckGameCenterLinkUrl);
//        HttpRequest request = new HttpRequest();
//        request.Request(reqUrl, postContent, callBack);
//    }
//
//    public void LinkNewGameCenter(string deviceId, string uuid, string playerId, HttpRequest.HttpRequestCallback callBack)
//    {
//        Dictionary<string, string> dic = new Dictionary<string, string>();
//        dic.Add("deviceID", deviceId);
//        dic.Add("uuid", uuid);
//        dic.Add("playerID", playerId);
//
//        string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//        string reqUrl = HttpRequestManager.GetRequestUrl(host,LinkNewGameCenterUrl);
//        HttpRequest request = new HttpRequest();
//        request.Request(reqUrl, postContent, callBack);
//    }

//	public void UnBindGameCenter(string deviceId, string uuid, string playerId, HttpRequest.HttpRequestCallback callBack)
//	{
//		Dictionary<string, string> dic = new Dictionary<string, string>();
//		dic.Add("deviceID", deviceId);
//		dic.Add("uuid", uuid);
//		dic.Add("playerID", playerId);
//		
//		string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//		string reqUrl = HttpRequestManager.GetRequestUrl(host,UnBindGameCenterUrl);
//		HttpRequest request = new HttpRequest();
//		request.Request(reqUrl, postContent, callBack);
//	}

//	public void CheckFacebookLink(string deviceId, string uuid, string facebookID, HttpRequest.HttpRequestCallback callBack)
//	{
//		Dictionary<string, string> dic = new Dictionary<string, string>();
//		dic.Add("deviceID", deviceId);
//		dic.Add("uuid", uuid);
//		dic.Add("facebookID", facebookID);
//		
//		string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//		string reqUrl = HttpRequestManager.GetRequestUrl(host,CheckFacebookLinkUrl);
//		HttpRequest request = new HttpRequest();
//		request.Request(reqUrl, postContent, callBack);
//	}

//	public void BindFacebook(string deviceId, string uuid, string facebookID, HttpRequest.HttpRequestCallback callBack)
//	{
//		Dictionary<string, string> dic = new Dictionary<string, string>();
//		dic.Add("deviceID", deviceId);
//		dic.Add("uuid", uuid);
//		dic.Add("facebookID", facebookID);
//		
//		string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//		string reqUrl = HttpRequestManager.GetRequestUrl(host,BindFacebookUrl);
//		HttpRequest request = new HttpRequest();
//		request.Request(reqUrl, postContent, callBack);
//	}
//	
//	public void UnBindFacebook(string deviceId, string uuid, string facebookID, HttpRequest.HttpRequestCallback callBack)
//	{
//		Dictionary<string, string> dic = new Dictionary<string, string>();
//		dic.Add("deviceID", deviceId);
//		dic.Add("uuid", uuid);
//		dic.Add("facebookID", facebookID);
//		
//		string postContent = JsonConvert.SerializeObject(dic);
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//		string reqUrl = HttpRequestManager.GetRequestUrl(host,UnBindFacebookUrl);
//		HttpRequest request = new HttpRequest();
//		request.Request(reqUrl, postContent, callBack);
//	}



//    public void CheckThirdPartLink(ThirdPartType type, string deviceId, string uuid, string accountId,string accountToken, HttpRequest.HttpRequestCallback callBack)
//    {
//        Dictionary<string, string> dic = new Dictionary<string, string>();
//        dic.Add("deviceID", deviceId);
//        dic.Add("uuid", uuid);
//        dic.Add("accountID", accountId);
//        dic.Add("accountToken", accountToken);
//        dic.Add("type",""+(int)type);
//
//        string postContent = JsonConvert.SerializeObject(dic);
//        string host = EvonyDataCenter.Instance.GetLoginURL();
//        string reqUrl = HttpRequestManager.GetRequestUrl(host, CheckThirdPartLinkUrl);
//        HttpRequest request = new HttpRequest();
//        request.Request(reqUrl, postContent, callBack);
//    }

//    public void BindThirdPart(ThirdPartType type, string deviceId, string uuid, string accountId, string accountToken, HttpRequest.HttpRequestCallback callBack)
//    {
//        Dictionary<string, string> dic = new Dictionary<string, string>();
//        dic.Add("deviceID", deviceId);
//        dic.Add("uuid", uuid);
//        dic.Add("accountID", accountId);
//        dic.Add("accountToken", accountToken);
//        dic.Add("type", "" + (int)type);
//
//        string postContent = JsonConvert.SerializeObject(dic);
//        string host = EvonyDataCenter.Instance.GetLoginURL();
//        string reqUrl = HttpRequestManager.GetRequestUrl(host, BindThirdPartUrl);
//        HttpRequest request = new HttpRequest();
//        request.Request(reqUrl, postContent, callBack);
//    }

//    public void UnBindThirdPart(ThirdPartType type, string deviceId, string uuid, string accountId, HttpRequest.HttpRequestCallback callBack)
//    {
//        Dictionary<string, string> dic = new Dictionary<string, string>();
//        dic.Add("deviceID", deviceId);
//        dic.Add("uuid", uuid);
//        dic.Add("accountID", accountId);
//        //dic.Add("accountToken", accountToken);
//        dic.Add("type", "" + (int)type);
//
//        string postContent = JsonConvert.SerializeObject(dic);
//        string host = EvonyDataCenter.Instance.GetLoginURL();
//        string reqUrl = HttpRequestManager.GetRequestUrl(host, UnBindThirdPartUrl);
//        HttpRequest request = new HttpRequest();
//        request.Request(reqUrl, postContent, callBack);
//    }

//	public object GetResourceVersion(uint crc, HttpRequest.HttpRequestCallback callBack)
//	{
//		string host=EvonyDataCenter.Instance.GetLoginURL();
//		string reqUrl = HttpRequestManager.GetRequestUrl(host,ResVersionApiUrl);
//		HttpRequest request = new HttpRequest();
//		request.Request(reqUrl, null, callBack);
//		return request;
//	}

	public bool cancelRequest(object obj)
	{
		if(obj == null)
		{
			return true;
		}

		if(obj is HttpRequest)
		{
			HttpRequest request = (HttpRequest)obj;
			request.Cancel();
			return true;
		}

		return false;
	}

//    public void TrackingStats(TrackingStatsType type, string strParams = "", bool paiallel = false)
//    {
//		return;
//
//        //TrackingStatsConfigure config = ConfigureManager.instance.GetTrackingConfig(type);
//        //if (config != null && config.isTracking == 0)
//        //{
//        //    return;
//        //}
//        if (Debug.enableLog)
//        {
//            Debug.Log("TrackingStats: " + type);
//        }
//
//        if (paiallel == false)
//        {
//            if (dicTrackHttpRequest.ContainsKey((int)type))
//            {
//                return;
//            }
//
//            string host = EvonyDataCenter.Instance.GetLoginURL();
//            string reqUrl = host + "pixel.jpg?client=u3d&os=" + (int)EvonyPlatform.getPlatform() + "&type=" + (int)type + "&user_id=" + Config.userId + "&isAmazon=0&hd=0&is50mClient=1";
//
//            if (Application.platform == RuntimePlatform.Android)
//            {
//                BundleVersionConfig config2 = BundleVersionManager.instance.GetBundleVersionConfig();
//                if (config2 != null)
//                {
//                    reqUrl += "&version=" + Version.version + "." + config2.version;
//                }
//                else
//                {
//                    reqUrl += "&version=" + Version.version + "." + Version.build_version;
//                }
//            }
//            else
//            {
//                reqUrl += "&version=" + Version.version + "." + Version.build_version;
//            }
//            reqUrl += "&uuid=" + Config.ClientUUID() + "&newbie=" + Config.NewBie() + "&compileType=" + SwitchConfig.compileType.ToString() + "&icp=" + SwitchConfig.icp + "&others=" + strParams + "&model=" + Config.Model();
//#if UNITY_ANDROID && !UNITY_EDITOR
//		reqUrl +="&channel="+ ChatPluginAndroid.Instance.getChannelName() + "&is50mClient="+ ChatPluginAndroid.Instance.is50mClient();
//#else
//            reqUrl += "&is50mClient=1";
//#endif
//            bool start = dicTrackHttpRequest.Count == 0 ? true : false;
//            HttpRequest request = new HttpRequest();
//            dicTrackHttpRequest[(int)type] = request;
//            listTrackHttpRequest.Add(request);
////            request.trackType = type;
//            request.notifyResponse = true;
//            request.Request(reqUrl, null, null, start, HttpRetryCount);
//        }
//        else
//        {
//            string host = EvonyDataCenter.Instance.GetLoginURL();
//            string reqUrl = host + "pixel.jpg?client=u3d&os=" + (int)EvonyPlatform.getPlatform() + "&type=" + (int)type + "&user_id=" + Config.userId + "&isAmazon=0&hd=0&is50mClient=1";
//
//            if (Application.platform == RuntimePlatform.Android)
//            {
//                BundleVersionConfig config2 = BundleVersionManager.instance.GetBundleVersionConfig();
//                if (config2 != null)
//                {
//                    reqUrl += "&version=" + Version.version + "." + config2.version;
//                }
//                else
//                {
//                    reqUrl += "&version=" + Version.version + "." + Version.build_version;
//                }
//            }
//            else
//            {
//                reqUrl += "&version=" + Version.version + "." + Version.build_version;
//            }
//            reqUrl += "&uuid=" + Config.ClientUUID() + "&newbie=" + Config.NewBie() + "&compileType=" + SwitchConfig.compileType.ToString() + "&icp=" + SwitchConfig.icp + "&others=" + strParams + "&model=" + Config.Model();
//#if UNITY_ANDROID && !UNITY_EDITOR
//		reqUrl +="&channel="+ ChatPluginAndroid.Instance.getChannelName() + "&is50mClient="+ ChatPluginAndroid.Instance.is50mClient();
//#else
//            reqUrl += "&is50mClient=1";
//#endif
//            bool start = true;
//            HttpRequest request = new HttpRequest();
////            request.trackType = type;
//            request.Request(reqUrl, null, null, start, HttpRetryCount);
//        }
//    }

	private static string GetRequestUrl(string host, string apiUrl, Dictionary<string, string> getParams = null)
	{
		return "";

		if (apiUrl == null)
		{
			return host;
		}

		string ret = host + "index.php?r=" + apiUrl + 
//			"&Language=" + (int)LocalizationManager.instance.CurrentLanguage + 
			"&appVersion=" + VersionEx.version_number + 
			"&platform=" + PlatformEx.getPlatform ().ToString () +
//			"&compileType=" + SwitchConfig.compileType.ToString() + 
            // "&icp=" + SwitchConfig.icp
            "";

		if(getParams != null)
		{
			Dictionary<string, string>.Enumerator enumerator = getParams.GetEnumerator();
			while(enumerator.MoveNext())
			{
				ret += "&" + enumerator.Current.Key + "=" + enumerator.Current.Value;
			}
		}
		return ret;
    }


	private static string GetRequestUrl2(string host, string apiUrl, Dictionary<string, string> getParams = null)
	{
		if (apiUrl == null)
		{
			return host;
		}
		
		string ret = host + "index2.php?r=" + apiUrl + 
//			"&Language=" + (int)LocalizationManager.instance.CurrentLanguage + 
				"&appVersion=" + VersionEx.version_number + 
				"&platform=" + PlatformEx.getPlatform ().ToString () +
//				"&compileType=" + SwitchConfig.compileType.ToString() + 
                "";
		
		if(getParams != null)
		{
			Dictionary<string, string>.Enumerator enumerator = getParams.GetEnumerator();
			while(enumerator.MoveNext())
			{
				ret += "&" + enumerator.Current.Key + "=" + enumerator.Current.Value;
			}
		}
		return ret;
	}

//    private void OnHttpResponse(DataChangeType type, params object[] objs)
//    {
//        if (objs == null || objs.Length == 0)
//        {
//            return;
//        }
//
//        HttpRequest request = (HttpRequest)objs[0];
//
////        if (Debug.enableLog)
////            Debug.Log("OnHttpResponse trackType: " + request.trackType + " success: " + request.success);
//
//        if (request.success == true)
//        {
//            listTrackHttpRequest.Remove(request);
//            foreach (int key in dicTrackHttpRequest.Keys)
//            {
//                if (dicTrackHttpRequest[key] == request)
//                {
//                    dicTrackHttpRequest.Remove(key);
//                    break;
//                }
//            }
//
//            if (listTrackHttpRequest.Count > 0)
//            {
//                request = listTrackHttpRequest[0];
//                request.Start();
//            }
//        }
//        else
//        {
//            _networkAvailable = false;
//        }
//    }

//    private void OnNetworkAvailable(DataChangeType type, params object[] objs)
//    {
//        if (_networkAvailable == true)
//        {
//            return;
//        }
//
//        _networkAvailable = true;
//        this.RetryHttpRequests();
//    }

    private void RetryHttpRequests()
    {
        if (listTrackHttpRequest.Count == 0)
        {
            return;
        }

        HttpRequest request = listTrackHttpRequest[0];
        request.Start();
    }

//    public void CancelAllRequest()
//    {
//        for (int i = 0; i < _arrRequest.Count; ++i)
//        {
//            HttpRequest request = _arrRequest[i];
//            request.Cancel();
//        }
//
//        _arrRequest.Clear();
//        _dicTypeToRequest.Clear();
//    }

//    public void UnsubscribeAll()
//    {
//        _httpRequestEventTable.Clear();
//    }
}
